
interface IPlayInfo {
  src: string;
  playbackRate?: number | undefined;
  onVoiceStart?: (() => void) | undefined;  /** 音频开始 */
  onVoiceStop?: (() => void) | undefined;   /** 音频停止 */
  onVoicePause?: (() => void) | undefined;   /** 音频暂停 */
  onVoiceEnded?: (() => void) | undefined;   /** 音频播放结束 */
}

export class AudioManager {
  private static instance: AudioManager;
  private audioContext: UniNamespace.InnerAudioContext | undefined = undefined;
  private onVoiceStart: (() => void) | undefined = undefined;
  private onVoiceStop: (() => void) | undefined = undefined;
  private onVoicePause: (() => void) | undefined = undefined;
  private onVoiceEnded: (() => void) | undefined = undefined;

  private constructor() {
  }

  public static getInstance() {
    if (!AudioManager.instance) {
      AudioManager.instance = new AudioManager();
      AudioManager.instance.configAudioContext();
    }

    return AudioManager.instance;
  }

  private configAudioContext() {
    console.log('创建音频播放器')
    this.audioContext = uni.createInnerAudioContext();
    uni.setInnerAudioOption({
      obeyMuteSwitch: false
    })
    this.audioContext.autoplay = true
    this.audioContext.onPlay(() => {
      if (this.onVoiceStart) {
        this.onVoiceStart!();
      }
    })
    this.audioContext.onEnded(() => {
      console.log('end')
      this.handleEnded()
    })

    this.audioContext.onError((res) => {
      this.handleStop()
    })

    this.audioContext.onStop(() => {
      console.log('stop')
      this.handleStop()
    })

    this.audioContext.onPause(() => {
      console.log('pause')
      if (this.onVoicePause) {
        this.onVoicePause!();
      }
    })
  }

  private handleEnded() {
    let onVoiceEnded = this.onVoiceEnded
    this.onVoiceEnded = undefined
    if (onVoiceEnded) {
      onVoiceEnded!();
    }
  }

  private handleStop() {
    let onVoiceStop = this.onVoiceStop
    // this.onVoiceStop = undefined
    if (onVoiceStop) {
      onVoiceStop!();
    }
  }

  public play(data: IPlayInfo) {
    this.onVoiceStart = undefined;
    this.handleStop()
    if (this.audioContext!.src === data.src) {
      this.audioContext!.stop()
      this.audioContext!.seek(0);
      this.audioContext!.play()
    } else {
      this.audioContext!.stop()
      this.audioContext!.src = data.src
      this.audioContext!.seek(0);
      this.audioContext!.play()
    }

    this.onVoiceStop = data.onVoiceStop;
    this.onVoiceStart = data.onVoiceStart;
    this.onVoicePause = data.onVoicePause;
    this.onVoiceEnded = data.onVoiceEnded;
  }

  public stop() {
    this.audioContext?.stop();
  }

  public pause(data?: IPlayInfo) {
    this.audioContext!.pause();

    if (data) {
      this.onVoicePause = data!.onVoicePause;
    }
  }
}
